package studia.figlewicz.math.library;

import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

public class ModelYieldCurve extends Model {

	public final static String[] nazwyZmiennychObjasniajacych = {
		ModelYieldCurve.ZMIENNA_OBJASNIAJACA_KONTRAKT
	};
	public final static String ZMIENNA_OBJASNIAJACA_KONTRAKT = Stale.MODEL_YIELD_CURVE_ZM_IR;
	public final static String[] nazwyZmiennychObjasnianych = {
		ModelYieldCurve.ZMIENNA_OBJASNIANA_STOPA_PROCENTOWA
	};
	public final static String ZMIENNA_OBJASNIANA_STOPA_PROCENTOWA = Stale.MODEL_YIELD_CURVE_WYNIK_IR;
	
	private MetodaInterpolacji interpolacja;
	
	
	// konstruktory
	public ModelYieldCurve(MetodaInterpolacji interpolacja) {
		super();
		for (String zm : nazwyZmiennychObjasniajacych) {
			zmienneObjasniajace.put(zm, null);
		}
		this.interpolacja = interpolacja;
	}
	
	
	// gettery i settery
	public MetodaInterpolacji getInterpolacja() {
		return interpolacja;
	}
	public void setInterpolacja(MetodaInterpolacji interpolacja) {
		this.interpolacja = interpolacja;
	}
	@Override
	public String[] getNazwyZmiennychObjasnianych() {
		return nazwyZmiennychObjasnianych;
	}
	@Override
	public String[] getNazwyZmiennychObjasniajacych() {
		return nazwyZmiennychObjasnianych;
	}
	
	
	// metody
	@Override
	public Map<String, TrajektoriaProcesu> utworzBuforWynikuProjekcji() {
		Map<String, TrajektoriaProcesu> resoult = new HashMap<String, TrajektoriaProcesu>();
		for (String zm : nazwyZmiennychObjasnianych) {
			resoult.put(zm, new TrajektoriaProcesu());
		}
		return resoult;
		
	}
	@Override
	public Map<String, Double> wyznaczKrokProjekcji(Date dzienProjekcji,  Map<String, TrajektoriaProcesu> dotychczasoweTrajektorie) {
		Map<String, Double> resoult = new HashMap<String, Double>();
		Double value = null;
		ZmiennaObjasniajaca krzywa = zmienneObjasniajace.get(ZMIENNA_OBJASNIAJACA_KONTRAKT);
		
		if (krzywa != null) {
			value = wartoscZmiennej(dzienProjekcji, krzywa);
		}

		resoult.put(ZMIENNA_OBJASNIANA_STOPA_PROCENTOWA, value);
		return resoult;
	}

	
	// metody prywatne
	@Override
	protected boolean isObjasniajaca(String nazwa) {
		boolean resoult = false;
		for (String zm : nazwyZmiennychObjasniajacych) {
			if (zm.equals(nazwa)) {
				resoult = true;
				break;
			}
		}
		
		return resoult;
	}
	@Override	
	protected boolean isObjasniana(String nazwa) {
		boolean resoult = false;
		for (String zm : nazwyZmiennychObjasnianych) {
			if (zm.equals(nazwa)) {
				resoult = true;
				break;
			}
		}
		
		return resoult;
	}
	private Double wartoscZmiennej(Date dzien, ZmiennaObjasniajaca zm) {
		Double resoult = null;
		LinkedHashMap<Date, Double> punkty = zm.getPunkty();
		
		if (punkty.size() == 1) {
			for (Date d : punkty.keySet())
				resoult = punkty.get(d);
		}
		else if (punkty.size() > 1) {
			Set<Date> datySasiednie = Utils.get2Sasiednie(punkty.keySet(), dzien);
		
			LinkedHashMap<Date, Double> punktySasiednie = new LinkedHashMap<Date, Double>();
			for (Date d : datySasiednie) {
				punktySasiednie.put(d,punkty.get(d));
			}
			
			resoult = new Double(Utils.wartoscWygladzona(punktySasiednie, dzien, interpolacja).doubleValue());
		}
		return resoult;
	}

	@Override
	public void inicjalucujProjekcje(Date poczatekSymulacji) {}
	
	
}
